package com.yxw.live_vod_boot.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yxw.live_vod_boot.dto.SendNormalMsgDto;
import com.yxw.live_vod_boot.dto.follow.*;
import com.yxw.live_vod_boot.entity.*;
import com.yxw.live_vod_boot.enums.MqttTopicEnum;
import com.yxw.live_vod_boot.mapper.FollowMapper;
import com.yxw.live_vod_boot.mapper.ShopMapper;
import com.yxw.live_vod_boot.mapper.UserMapper;
import com.yxw.live_vod_boot.mqtt.MqttGateway;
import com.yxw.live_vod_boot.service.FollowService;
import com.yxw.live_vod_boot.service.LiveGeneraUserProcessService;
import com.yxw.live_vod_boot.service.SysNoticeService;
import com.yxw.live_vod_boot.utils.AssertUtil;
import com.yxw.live_vod_boot.utils.JsonUtils;
import com.yxw.live_vod_boot.utils.PageUtils;
import com.yxw.live_vod_boot.utils.RedisManager;
import com.yxw.live_vod_boot.vo.*;
import com.yxw.live_vod_facade.constant.LiveShopConstant;
import com.yxw.yxnet_cd_center.common.dto.PageVO;
import com.yxw.yxnet_cd_center.common.enums.ErrorCodeEnum;
import com.yxw.yxnet_cd_center.common.utils.BaseResult;
import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import javax.annotation.Resource;

import org.springframework.data.redis.core.RedisTemplate;

/**
 * @author fangmaoxin
 * &#064;date  2023年11月21日
 */
@Service
@Slf4j
public class FollowServiceImpl extends ServiceImpl<FollowMapper, YxFollowEntity> implements FollowService {

    @Autowired
    private FollowMapper followMapper;

    @Autowired
    private SysNoticeService sysNoticeService;

    @Autowired
    private LiveGeneraUserProcessService liveGeneraUserProcessService;

    @Resource
    private RedisManager oRedisManager;

    @Autowired
    private MqttGateway mqttGateway;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private ShopMapper shopMapper;

    /**
     * 用户侧-查询自己的关注列表
     */
    @Override
    public PageVO<FollowListVO> getFollowListByUserId(Long userId, FollowQueryDTO dto) {
        AssertUtil.isNotNull(userId, ErrorCodeEnum.COLLECTION_USER_ID_ERROR);
        Page<YxFollowEntity> page = new Page<>(dto.getCurrPage(), dto.getPageSize());
        List<FollowListVO> result = followMapper.selectUserFollowList(page, userId);
        // 校验店铺是否在直播
        for (FollowListVO followListVO : result) {
            if (0 == followListVO.getUserType() && null != followListVO.getShopId()) {
                Long shopId = followListVO.getShopId();
                BaseResult baseResult = liveGeneraUserProcessService.userCheckShopLiveStreamIsActive(shopId);
                if (baseResult.isResult()) {
                    LiveOnlineInRedisCacheVO oLiveOnlineInRedisCacheVO = (LiveOnlineInRedisCacheVO) baseResult.getData();
                    followListVO.setLiveVO(oLiveOnlineInRedisCacheVO);
                    followListVO.setLiveState(1);
                } else {
                    followListVO.setLiveState(0);
                }
            }
        }
        return PageUtils.get(page, result);
    }

    /**
     * 用户侧-新朋友列表
     */
    @Override
    public PageVO<NewFriendListVO> getNewFriendList(Long userId, NewFriendQueryDTO dto) {
        AssertUtil.isNotNull(userId, ErrorCodeEnum.COLLECTION_USER_ID_ERROR);
        Page<YxFollowEntity> page = new Page<>(dto.getCurrPage(), dto.getPageSize());
        List<NewFriendListVO> list = followMapper.getNewFriendList(page, userId);
        for (NewFriendListVO listVO : list) {
            FollowStateQueryDTO followStateQueryDTO = new FollowStateQueryDTO();
            followStateQueryDTO.setFollowerType(1);
            followStateQueryDTO.setFolloweeId(listVO.getUserId());
            followStateQueryDTO.setFolloweeType(listVO.getUserType());
            if (null != listVO.getShopId()) {
                followStateQueryDTO.setFolloweeShopId(listVO.getShopId());
            }
            FollowStateVO state = this.checkFollowStateForUser(userId, followStateQueryDTO);
            if (null != state && null != state.getFollowState()) {
                if (Boolean.TRUE.equals(state.getFollowState())) {
                    listVO.setIsFollowed(0);
                } else {
                    listVO.setIsFollowed(1);
                }
            }
        }
        return PageUtils.get(page, list);
    }

    /**
     * 店铺侧-新朋友列表
     */
    @Override
    public PageVO<NewFriendListVO> getShopNewFriendList(Long userId, ShopNewFriendQueryDTO dto) {
        AssertUtil.isNotNull(userId, ErrorCodeEnum.COLLECTION_USER_ID_ERROR);
        Page<YxFollowEntity> page = new Page<>(dto.getCurrPage(), dto.getPageSize());
        List<NewFriendListVO> list = followMapper.getShopNewFriendList(page, userId, dto);
        for (NewFriendListVO listVO : list) {
            FollowStateQueryDTO followStateQueryDTO = new FollowStateQueryDTO();
            followStateQueryDTO.setFollowerType(0);
            followStateQueryDTO.setFolloweeId(listVO.getUserId());
            followStateQueryDTO.setFolloweeType(listVO.getUserType());
            followStateQueryDTO.setFollowerShopId(dto.getShopId());
            if (null != listVO.getShopId()) {
                followStateQueryDTO.setFolloweeShopId(listVO.getShopId());
            }
            FollowStateVO state = this.checkFollowStateForUser(userId, followStateQueryDTO);
            if (null != state && null != state.getFollowState()) {
                if (Boolean.TRUE.equals(state.getFollowState())) {
                    listVO.setIsFollowed(0);
                } else {
                    listVO.setIsFollowed(1);
                }
            }
        }
        return PageUtils.get(page, list);
    }

    /**
     * 用户新增一个关注
     */
    @Override
    @Transactional
    public int insertFollowByUserId(Long userId, FollowAddDTO dto) {
        AssertUtil.isNotNull(userId, ErrorCodeEnum.COLLECTION_USER_ID_ERROR);
        LambdaQueryWrapper<YxFollowEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(YxFollowEntity::getFollowerId, userId);
        queryWrapper.eq(YxFollowEntity::getFollowerType, dto.getFollowerType());
        queryWrapper.eq(YxFollowEntity::getFolloweeId, dto.getFolloweeId());
        queryWrapper.eq(YxFollowEntity::getFolloweeType, dto.getFolloweeType());
        if (null != dto.getFolloweeShopId()) {
            queryWrapper.eq(YxFollowEntity::getFolloweeShopId, dto.getFolloweeShopId());
        }
        if (null != dto.getFollowerShopId()) {
            queryWrapper.eq(YxFollowEntity::getFollowerShopId, dto.getFollowerShopId());
        }
        YxFollowEntity selectOne = baseMapper.selectOne(queryWrapper);
        AssertUtil.isNull(selectOne, ErrorCodeEnum.FOLLOW_IS_EXIST);
        YxFollowEntity yxFollowEntity = getFollowEntity(userId, dto);
        int cnt = baseMapper.insert(yxFollowEntity);
        if (yxFollowEntity.getFollowerType() == 1 && yxFollowEntity.getFolloweeType() == 0 && null != yxFollowEntity.getFolloweeShopId()) {
            //关注过的店铺
            String redisKey = LiveShopConstant.LIVE_SHOP_USER_FOLLOW_SHOP_HASHMAP_PREFIX.concat(userId.toString());
            oRedisManager.setMapValue(redisKey, yxFollowEntity.getFolloweeShopId().toString(), yxFollowEntity.getFolloweeShopId().toString());
        }
        //发送关注信息
        SendNormalMsgDto msgDto = new SendNormalMsgDto();
        if (0 == dto.getFolloweeType()) {
            msgDto.setShopId(dto.getFolloweeShopId());
            msgDto.setShopName(dto.getFolloweeShopName());
        } else {
            msgDto.setUserName(dto.getFolloweeName());
            msgDto.setUserId(dto.getFolloweeId());
        }
        msgDto.setType(1);
        sysNoticeService.sendNormalNotice(msgDto);
        // 直播间发送关注消息
        sendLiveFollowMsg(userId, dto);
        return cnt;
    }

    private void sendLiveFollowMsg(Long userId, FollowAddDTO dto) {
        if (1 == dto.getFollowScene() && null != dto.getLiveId() && 1 == dto.getFollowerType() && 0 == dto.getFolloweeType()) {
            // 发送评论消息
            MqttLiveCommentVo mqttVo = new MqttLiveCommentVo();
            mqttVo.setType(4);
            // 接收人ID
            mqttVo.setReceiverId(dto.getLiveId());
            mqttVo.setSysTime(new Date());
            // 内容
            YxSysUserEntity yxSysUserEntity = userMapper.selectById(userId);
            if (null != yxSysUserEntity && null != yxSysUserEntity.getNickName()) {
                mqttVo.setContent(yxSysUserEntity.getNickName() + " 关注了直播间");
            }
            log.info("推送直播ID=============================================>{}", dto.getLiveId());
            log.info("推送评论内容=============================================>{}", mqttVo.getContent());
            mqttGateway.sendToMqtt(MqttTopicEnum.LIVE_COMMENT_TOPIC.getTopic() + dto.getLiveId(), JsonUtils.toJson(mqttVo));
        }
    }

    private YxFollowEntity getFollowEntity(Long userId, FollowAddDTO dto) {
        YxFollowEntity yxFollowEntity = new YxFollowEntity();
        yxFollowEntity.setFollowerId(userId);
        yxFollowEntity.setFollowerType(dto.getFollowerType());
        if (null == dto.getFolloweeId() && null != dto.getFolloweeShopId()) {
            Long shopUserId = followMapper.getShopUserId(dto.getFolloweeShopId());
            if (null != shopUserId) {
                yxFollowEntity.setFolloweeId(shopUserId);
            } else {
                yxFollowEntity.setFolloweeId(dto.getFolloweeId());
            }
        } else if (null != dto.getFolloweeId() && null == dto.getFolloweeShopId()) {
            yxFollowEntity.setFolloweeId(dto.getFolloweeId());
        }
        // 当关注者为用户的时候，不需要店铺id
        if (null != dto.getFollowerType() && Integer.valueOf(1).equals(dto.getFollowerType())) {
            yxFollowEntity.setFollowerShopId(null);
        } else {
            yxFollowEntity.setFollowerShopId(dto.getFollowerShopId());
        }
        // 当被关注者为用户的时候，不需要店铺id
        if (null != dto.getFolloweeType() && Integer.valueOf(1).equals(dto.getFolloweeType())) {
            yxFollowEntity.setFolloweeShopId(null);
        } else {
            yxFollowEntity.setFolloweeShopId(dto.getFolloweeShopId());
        }
        yxFollowEntity.setFolloweeType(dto.getFolloweeType());
        yxFollowEntity.setFollowScene(dto.getFollowScene());
        yxFollowEntity.setFollowTime(new Date());
        yxFollowEntity.setFollowStatus(0);
        yxFollowEntity.setCreateTime(new Date());
        return yxFollowEntity;
    }

    /**
     * 用户取消一个关注
     */
    @Override
    @Transactional
    public int deleteFollowByUserId(FollowDeleteDTO dto) {
        AssertUtil.isNotNull(dto.getFollowerId(), ErrorCodeEnum.COLLECTION_USER_ID_ERROR);
        // 校验取消关注的存不存在
        LambdaQueryWrapper<YxFollowEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(YxFollowEntity::getFollowerId, dto.getFollowerId());
        wrapper.eq(YxFollowEntity::getFollowerType, dto.getFollowerType());
        wrapper.eq(YxFollowEntity::getFolloweeType, dto.getFolloweeType());
        wrapper.eq(YxFollowEntity::getFolloweeId, dto.getFolloweeId());
        if (null != dto.getFollowerShopId()) {
            wrapper.eq(YxFollowEntity::getFollowerShopId, dto.getFollowerShopId());
        }
        if (null != dto.getFolloweeShopId()) {
            wrapper.eq(YxFollowEntity::getFolloweeShopId, dto.getFolloweeShopId());
        }
        YxFollowEntity selectOne = baseMapper.selectOne(wrapper);
        AssertUtil.isNotNull(selectOne, ErrorCodeEnum.FOLLOW_NOT_EXIST);

        // 删除关注记录
        int iCounter = baseMapper.delete(wrapper);
        if (selectOne.getFollowerType() == 1 && selectOne.getFolloweeType() == 0 && null != selectOne.getFolloweeShopId()) {
            //取消关注过的店铺
            String redisKey = LiveShopConstant.LIVE_SHOP_USER_FOLLOW_SHOP_HASHMAP_PREFIX.concat(selectOne.getFollowerId().toString());
            oRedisManager.delMapValue(redisKey, selectOne.getFolloweeShopId().toString());
        }
        return iCounter;
    }

    /**
     * 查询自己有没有关注某个用户/店铺
     */
    @Override
    public FollowStateVO checkFollowStateForUser(Long userId, FollowStateQueryDTO dto) {
        AssertUtil.isNotNull(userId, ErrorCodeEnum.COLLECTION_USER_ID_ERROR);
        LambdaQueryWrapper<YxFollowEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(YxFollowEntity::getFollowerId, userId);
        wrapper.eq(YxFollowEntity::getFollowerType, dto.getFollowerType());
        wrapper.eq(YxFollowEntity::getFolloweeType, dto.getFolloweeType());
        if (null == dto.getFolloweeId() && Integer.valueOf(0).equals(dto.getFolloweeType()) && null != dto.getFolloweeShopId()) {
            LambdaQueryWrapper<YxLiveShopEntity> shopWrapper = new LambdaQueryWrapper<>();
            shopWrapper.eq(YxLiveShopEntity::getLiveShopId, dto.getFolloweeShopId());
            YxLiveShopEntity liveShop = shopMapper.selectOne(shopWrapper);
            if (null != liveShop && null != liveShop.getUserId()){
                wrapper.eq(YxFollowEntity::getFolloweeId, liveShop.getUserId());
            }
        } else {
            wrapper.eq(YxFollowEntity::getFolloweeId, dto.getFolloweeId());
        }
        if (null != dto.getFolloweeShopId()) {
            wrapper.eq(YxFollowEntity::getFolloweeShopId, dto.getFolloweeShopId());
        }
        if (null != dto.getFollowerShopId()) {
            wrapper.eq(YxFollowEntity::getFollowerShopId, dto.getFollowerShopId());
        }
        YxFollowEntity selectOne = baseMapper.selectOne(wrapper);
        FollowStateVO stateVO = new FollowStateVO();
        stateVO.setFollowState(null != selectOne);
        return stateVO;
    }
}
